home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / cujaug93.zip / 1108074A < prev    next >
Text File  |  1993-06-08  |  27KB  |  867 lines

  1.      /*******************************************
  2.      *
  3.      *   special_opening(...
  4.      *
  5.      *   Opening is erosion followed by dilation.
  6.      *   This routine will use the thinning
  7.      *   erosion routine.  This will not allow
  8.      *   an object to erode to nothing.
  9.      *
  10.      *   The number parameter specifies how
  11.      *   erosions to perform before doing one
  12.      *   dilation.
  13.      *
  14.      *******************************************/
  15.  
  16. special_opening(in_name, out_name, the_image,
  17.                 out_image, il, ie, ll, le,
  18.                 value, threshold, number)
  19.    char   in_name[], out_name[];
  20.    int    il, ie, ll, le, number;
  21.    short  the_image[ROWS][COLS],
  22.           out_image[ROWS][COLS],
  23.           threshold, value;
  24. {
  25.    int    a, b, count, i, j, k;
  26.    int    length, width;
  27.    struct tiff_header_struct image_header;
  28.  
  29.    if(does_not_exist(out_name)){
  30.       printf("\n\n output file does not exist %s", out_name);
  31.       read_tiff_header(in_name, &image_header);
  32.       round_off_image_size(&image_header,
  33.                            &length, &width);
  34.       image_header.image_length = length*ROWS;
  35.       image_header.image_width  = width*COLS;
  36.       create_allocate_tiff_file(out_name, &image_header,
  37.                                 out_image);
  38.    }  /* ends if does_not_exist */
  39.  
  40.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  41.  
  42.    thinning(in_name, out_name, the_image,
  43.             out_image, il, ie, ll, le,
  44.             value, threshold, 1);
  45.  
  46.    if(number > 1){
  47.       count = 1;
  48.       while(count < number){
  49.          count++;
  50.          thinning(out_name, out_name, the_image,
  51.                   out_image, il, ie, ll, le,
  52.                   value, threshold, 1);
  53.       }  /* ends while */
  54.    }  /* ends if number > 1 */
  55.  
  56.    dilation(out_name, out_name, the_image,
  57.             out_image, il, ie, ll, le,
  58.             value, threshold);
  59.  
  60.    write_array_into_tiff_image(out_name, out_image,
  61.                                il, ie, ll, le);
  62.  
  63. }  /* ends special_opening */
  64.  
  65.  
  66.  
  67.  
  68.      /*******************************************
  69.      *
  70.      *   thinning(...
  71.      *
  72.      *   Use a variation of the grass fire
  73.      *   wave front approach.
  74.      *
  75.      *   Raster scan the image left to right
  76.      *   and examine and thin the left edge pixels
  77.      *   (a 0 to value transition).  Process them
  78.      *   normally and "save" the result.  Next,
  79.      *   raster scan the image right to left and
  80.      *   save.  Raster scan top to bottom and save.
  81.      *   Raster scan bottom to top and save.
  82.      *
  83.      *   That is one complete pass.
  84.      *
  85.      *   Keep track of pixels thinned for a
  86.      *   pass and quit when you make a complete
  87.      *   pass without thinning any pixels.
  88.      *
  89.      *******************************************/
  90.  
  91. thinning(in_name, out_name, the_image, out_image,
  92.          il, ie, ll, le, value, threshold, once_only)
  93.    char   in_name[], out_name[];
  94.    int    il, ie, ll, le, once_only;
  95.    short  the_image[ROWS][COLS],
  96.           out_image[ROWS][COLS],
  97.           threshold, value;
  98. {
  99.    int    a, b, big_count, count, i, j, k,
  100.           not_finished;
  101.    int    length, width;
  102.    struct tiff_header_struct image_header;
  103.  
  104.    if(does_not_exist(out_name)){
  105.       printf("\n\n output file does not exist %s", out_name);
  106.       read_tiff_header(in_name, &image_header);
  107.       round_off_image_size(&image_header,
  108.                            &length, &width);
  109.       image_header.image_length = length*ROWS;
  110.       image_header.image_width  = width*COLS;
  111.       create_allocate_tiff_file(out_name, &image_header,
  112.                                 out_image);
  113.    }  /* ends if does_not_exist */
  114.  
  115.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  116.  
  117.  
  118.    for(i=0; i<ROWS; i++)
  119.       for(j=0; j<COLS; j++)
  120.          out_image[i][j] = the_image[i][j];
  121.  
  122.    not_finished = 1;
  123.    while(not_finished){
  124.  
  125.       if(once_only == 1)
  126.         not_finished = 0;
  127.       big_count = 0;
  128.  
  129.          /***************************
  130.          *
  131.          *   Scan left to right
  132.          *   Look for 0-value transition
  133.          *
  134.          ****************************/
  135.  
  136.       printf("\n");
  137.       for(i=1; i<ROWS-1; i++){
  138.          if( (i%10) == 0) printf("%3d", i);
  139.          for(j=1; j<COLS-1; j++){
  140.             if(the_image[i][j-1] == 0   &&
  141.                the_image[i][j]   == value){
  142.                count = 0;
  143.                for(a=-1; a<=1; a++){
  144.                    for(b=-1; b<=1; b++){
  145.                          if(the_image[i+a][j+b] == 0)
  146.                             count++;
  147.                    }  /*  ends loop over b */
  148.                }  /* ends loop over a */
  149.                if(count > threshold){
  150.                   if(can_thin(the_image, i, j, value)){
  151.                      out_image[i][j] = 0;
  152.                      big_count++;
  153.                   }  /* ends if can_thin */
  154.                }  /* ends if count > threshold */
  155.             }  /* ends if the_image == value */
  156.          }  /* ends loop over j */
  157.       }  /* ends loop over i */
  158.  
  159.          /**************************************
  160.          *
  161.          *   Copy the output back to the input.
  162.          *
  163.          **************************************/
  164.  
  165.       for(i=0; i<ROWS; i++)
  166.          for(j=0; j<COLS; j++)
  167.             the_image[i][j] = out_image[i][j];
  168.  
  169.  
  170.          /***************************
  171.          *
  172.          *   Scan right to left
  173.          *   Do this by scanning left
  174.          *   to right and look for
  175.          *   value-0 transition.
  176.          *
  177.          ****************************/
  178.  
  179.       printf("\n");
  180.       for(i=1; i<ROWS-1; i++){
  181.          if( (i%10) == 0) printf("%3d", i);
  182.          for(j=1; j<COLS-1; j++){
  183.             if(the_image[i][j+1] == 0   &&
  184.                the_image[i][j]   == value){
  185.                count = 0;
  186.                for(a=-1; a<=1; a++){
  187.                    for(b=-1; b<=1; b++){
  188.                          if(the_image[i+a][j+b] == 0)
  189.                             count++;
  190.                    }  /*  ends loop over b */
  191.                }  /* ends loop over a */
  192.                if(count > threshold){
  193.                   if(can_thin(the_image, i, j, value)){
  194.                      out_image[i][j] = 0;
  195.                      big_count++;
  196.                   }  /* ends if can_thin */
  197.                }  /* ends if count > threshold */
  198.             }  /* ends if the_image == value */
  199.          }  /* ends loop over j */
  200.       }  /* ends loop over i */
  201.  
  202.          /**************************************
  203.          *
  204.          *   Copy the output back to the input.
  205.          *
  206.          **************************************/
  207.       for(i=0; i<ROWS; i++)
  208.          for(j=0; j<COLS; j++)
  209.             the_image[i][j] = out_image[i][j];
  210.  
  211.  
  212.          /***************************
  213.          *
  214.          *   Scan top to bottom
  215.          *   Look for 0-value transition
  216.          *
  217.          ****************************/
  218.  
  219.       printf("\n");
  220.       for(j=1; j<COLS-1; j++){
  221.          if( (j%10) == 0) printf("%3d", j);
  222.          for(i=1; i<ROWS-1; i++){
  223.             if(the_image[i-1][j] == 0   &&
  224.                the_image[i][j]   == value){
  225.                count = 0;
  226.                for(a=-1; a<=1; a++){
  227.                    for(b=-1; b<=1; b++){
  228.                          if(the_image[i+a][j+b] == 0)
  229.                             count++;
  230.                    }  /*  ends loop over b */
  231.                }  /* ends loop over a */
  232.                if(count > threshold){
  233.                   if(can_thin(the_image, i, j, value)){
  234.                      out_image[i][j] = 0;
  235.                      big_count++;
  236.                   }  /* ends if can_thin */
  237.                }  /* ends if count > threshold */
  238.             }  /* ends if the_image == value */
  239.          }  /* ends loop over i */
  240.       }  /* ends loop over j */
  241.  
  242.          /**************************************
  243.          *
  244.          *   Copy the output back to the input.
  245.          *
  246.          **************************************/
  247.  
  248.       for(i=0; i<ROWS; i++)
  249.          for(j=0; j<COLS; j++)
  250.             the_image[i][j] = out_image[i][j];
  251.  
  252.  
  253.          /***************************
  254.          *
  255.          *   Scan bottom to top
  256.          *   Do this by scanning top
  257.          *   to bottom and look for
  258.          *   value-0 transition.
  259.          *
  260.          ****************************/
  261.  
  262.       printf("\n");
  263.       for(j=1; j<COLS-1; j++){
  264.          if( (j%10) == 0) printf("%3d", j);
  265.          for(i=1; i<ROWS-1; i++){
  266.             if(the_image[i+1][j] == 0   &&
  267.                the_image[i][j]   == value){
  268.                count = 0;
  269.                for(a=-1; a<=1; a++){
  270.                    for(b=-1; b<=1; b++){
  271.                          if(the_image[i+a][j+b] == 0)
  272.                             count++;
  273.                    }  /*  ends loop over b */
  274.                }  /* ends loop over a */
  275.                if(count > threshold){
  276.                   if(can_thin(the_image, i, j, value)){
  277.                      out_image[i][j] = 0;
  278.                      big_count++;
  279.                   }  /* ends if can_thin */
  280.                }  /* ends if count > threshold */
  281.             }  /* ends if the_image == value */
  282.          }  /* ends loop over i */
  283.       }  /* ends loop over j */
  284.  
  285.          /**************************************
  286.          *
  287.          *   Copy the output back to the input.
  288.          *
  289.          **************************************/
  290.  
  291.       for(i=0; i<ROWS; i++)
  292.          for(j=0; j<COLS; j++)
  293.             the_image[i][j] = out_image[i][j];
  294.  
  295.          /**************************************
  296.          *
  297.          *   Now look at the result of this big
  298.          *   pass through the image.
  299.          *
  300.          ***************************************/
  301.  
  302.       printf("\n\nThinned %d pixels", big_count);
  303.       if(big_count == 0)
  304.          not_finished = 0;
  305.       else{
  306.          for(i=0; i<ROWS; i++)
  307.             for(j=0; j<COLS; j++)
  308.                the_image[i][j] = out_image[i][j];
  309.       }  /* ends else */
  310.  
  311.    }  /* ends while not_finished */
  312.  
  313.    fix_edges(out_image, 3);
  314.    write_array_into_tiff_image(out_name, out_image,
  315.                                il, ie, ll, le);
  316. }  /* ends thinning */
  317.  
  318.  
  319.  
  320.  
  321.  
  322.      /*******************************************
  323.      *
  324.      *   can_thin(...
  325.      *
  326.      *   Look at the neighbors of the center pixel.
  327.      *   If a neighbor == value, then it must
  328.      *   have a neighbor == value other than the
  329.      *   center pixel.
  330.      *
  331.      *   Procedure:
  332.      *   . Copy the 3x3 area surrounding pixel
  333.      *     i,j to a temp array.
  334.      *   . Set the center pixel to zero.
  335.      *   . Look at each non-zero pixel in temp.
  336.      *      . If you cannot find a non-zero
  337.      *        neighbor.
  338.      *      . Then you cannot thin.
  339.      *
  340.      *******************************************/
  341.  
  342. can_thin(the_image, i, j, value)
  343.    int   i, j;
  344.    short the_image[ROWS][COLS], value;
  345. {
  346.    int   a, b, c, d, count,
  347.          no_neighbor, one=1, zero=0;
  348.    short temp[3][3];
  349.  
  350.        /**************************************
  351.        *
  352.        *   Copy the center pixel and its
  353.        *   neighbors to the temp array.
  354.        *
  355.        ***************************************/
  356.  
  357.    for(a=-1; a<2; a++)
  358.       for(b=-1; b<2; b++)
  359.          temp[a+1][b+1] = the_image[i+a][b+j];
  360.  
  361.        /**************************************
  362.        *
  363.        *   Set the center of temp to 0.
  364.        *
  365.        ***************************************/
  366.  
  367.    temp[1][1] = 0;
  368.  
  369.        /**************************************
  370.        *
  371.        *   Check the non-zero pixels in temp.
  372.        *
  373.        ***************************************/
  374.  
  375.    for(a=0; a<3; a++){
  376.       for(b=0; b<3; b++){
  377.          if(temp[a][b] == value){
  378.             temp[a][b] = 0;
  379.  
  380.                 /**************************************
  381.                 *
  382.                 *   Check the neighbors of this pixel
  383.                 *   If there is a single non-zero
  384.                 *   neighbor, set no_neighbor = 0.
  385.                 *
  386.                 ***************************************/
  387.  
  388.             no_neighbor = 1;
  389.             for(c=-1; c<2; c++){
  390.                for(d=-1; d<2; d++){
  391.                   if( ((a+c) >= 0)   &&
  392.                       ((a+c) <= 2)   &&
  393.                       ((b+d) >= 0)   &&
  394.                       ((b+d) <= 2)){
  395.                      if(temp[a+c][b+d] == value){
  396.                         no_neighbor = 0;
  397.                      }  /* ends if temp == value */
  398.                   }  /* ends if part of temp array */
  399.                }  /* ends loop over d */
  400.             }  /* ends loop over c */
  401.             temp[a][b] = value;
  402.  
  403.                 /**************************************
  404.                 *
  405.                 *   If the non-zero pixel did not
  406.                 *   have any non-zero neighbors,
  407.                 *   no_neighbor still equals 1,
  408.                 *   and we cannot thin, so return
  409.                 *   zero.
  410.                 *
  411.                 ***************************************/
  412.  
  413.             if(no_neighbor){
  414.                return(zero);
  415.             }
  416.          }  /* ends if temp[a][b] == value */
  417.       }  /* ends loop over b */
  418.    }  /* ends loop over a */
  419.  
  420.    return(one);
  421.  
  422. }  /* ends can_thin */
  423.  
  424.  
  425.  
  426.  
  427.  
  428.      /*******************************************
  429.      *
  430.      *   special_closing(...
  431.      *
  432.      *   Closing is dilation followed by erosion.
  433.      *   This routine will use the dilate_not_join
  434.      *   dilation routine.  This will not allow
  435.      *   two separate objects to join.
  436.      *
  437.      *   The number parameter specifies how
  438.      *   dilations to perform before doing one
  439.      *   erosion.
  440.      *
  441.      *******************************************/
  442.  
  443. special_closing(in_name, out_name, the_image,
  444.                 out_image, il, ie, ll, le,
  445.                 value, threshold, number)
  446.    char   in_name[], out_name[];
  447.    int    il, ie, ll, le, number;
  448.    short  the_image[ROWS][COLS],
  449.           out_image[ROWS][COLS],
  450.           threshold, value;
  451. {
  452.    int    a, b, count, i, j, k;
  453.    int    length, width;
  454.    struct tiff_header_struct image_header;
  455.  
  456.    if(does_not_exist(out_name)){
  457.       printf("\n\n output file does not exist %s", out_name);
  458.       read_tiff_header(in_name, &image_header);
  459.       round_off_image_size(&image_header,
  460.                            &length, &width);
  461.       image_header.image_length = length*ROWS;
  462.       image_header.image_width  = width*COLS;
  463.       create_allocate_tiff_file(out_name, &image_header,
  464.                                 out_image);
  465.    }  /* ends if does_not_exist */
  466.  
  467.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  468.  
  469.    dilate_not_join(in_name, out_name, the_image,
  470.                    out_image, il, ie, ll, le,
  471.                    value, threshold);
  472.  
  473.    if(number > 1){
  474.       count = 1;
  475.       while(count < number){
  476.          count++;
  477.          dilate_not_join(out_name, out_name, the_image,
  478.                          out_image, il, ie, ll, le,
  479.                          value, threshold);
  480.       }  /* ends while */
  481.    }  /* ends if number > 1 */
  482.  
  483.    erosion(out_name, out_name, the_image,
  484.            out_image, il, ie, ll, le,
  485.            value, threshold);
  486.  
  487.    write_array_into_tiff_image(out_name, out_image,
  488.                                il, ie, ll, le);
  489.  
  490. }  /* ends special_closing */
  491.  
  492.  
  493.  
  494.  
  495.      /*******************************************
  496.      *
  497.      *   dilate_not_join(...
  498.      *
  499.      *   Use a variation of the grass fire
  500.      *   wave front approach.
  501.      *
  502.      *   Raster scan the image left to right
  503.      *   and examine and dilate the left edge pixels
  504.      *   (a value to 0 transition).  Process them
  505.      *   normally and "save" the result.  Next,
  506.      *   raster scan the image right to left and
  507.      *   save.  Raster scan top to bottom and save.
  508.      *   Raster scan bottom to top and save.
  509.      *
  510.      *   That is one complete pass.
  511.      *
  512.      *******************************************/
  513.  
  514. dilate_not_join(in_name, out_name, the_image, out_image,
  515.                 il, ie, ll, le, value, threshold)
  516.    char   in_name[], out_name[];
  517.    int    il, ie, ll, le;
  518.    short  the_image[ROWS][COLS],
  519.           out_image[ROWS][COLS],
  520.           threshold, value;
  521. {
  522.    int    a, b, count, i, j, k;
  523.    int    length, width;
  524.    struct tiff_header_struct image_header;
  525.  
  526.    if(does_not_exist(out_name)){
  527.       printf("\n\n output file does not exist %s", out_name);
  528.       read_tiff_header(in_name, &image_header);
  529.       round_off_image_size(&image_header,
  530.                            &length, &width);
  531.       image_header.image_length = length*ROWS;
  532.       image_header.image_width  = width*COLS;
  533.       create_allocate_tiff_file(out_name, &image_header,
  534.                                 out_image);
  535.    }  /* ends if does_not_exist */
  536.  
  537.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  538.  
  539.  
  540.    for(i=0; i<ROWS; i++)
  541.       for(j=0; j<COLS; j++)
  542.          out_image[i][j] = the_image[i][j];
  543.  
  544.          /***************************
  545.          *
  546.          *   Scan left to right
  547.          *   Look for value-0 transition
  548.          *
  549.          ****************************/
  550.  
  551.       printf("\n");
  552.       for(i=1; i<ROWS-1; i++){
  553.          if( (i%10) == 0) printf("%3d", i);
  554.          for(j=1; j<COLS-1; j++){
  555.             if(the_image[i][j-1] == value  &&
  556.                the_image[i][j]   == 0){
  557.                count = 0;
  558.                for(a=-1; a<=1; a++){
  559.                    for(b=-1; b<=1; b++){
  560.                          if(the_image[i+a][j+b]==value)
  561.                             count++;
  562.                    }  /*  ends loop over b */
  563.                }  /* ends loop over a */
  564.                if(count > threshold){
  565.                   if(can_dilate(the_image,i,j,value)){
  566.                      out_image[i][j] = value;
  567.                   }  /* ends if can_dilate */
  568.                }  /* ends if count > threshold */
  569.             }  /* ends if the_image == value */
  570.          }  /* ends loop over j */
  571.       }  /* ends loop over i */
  572.  
  573.          /**************************************
  574.          *
  575.          *   Copy the output back to the input.
  576.          *
  577.          **************************************/
  578.  
  579.       for(i=0; i<ROWS; i++)
  580.          for(j=0; j<COLS; j++)
  581.             the_image[i][j] = out_image[i][j];
  582.  
  583.          /***************************
  584.          *
  585.          *   Scan right to left
  586.          *   Do this by scanning left
  587.          *   to right and look for
  588.          *   0-value transition.
  589.          *
  590.          ****************************/
  591.  
  592.       printf("\n");
  593.       for(i=1; i<ROWS-1; i++){
  594.          if( (i%10) == 0) printf("%3d", i);
  595.          for(j=1; j<COLS-1; j++){
  596.             if(the_image[i][j+1] == value   &&
  597.                the_image[i][j]   == 0){
  598.                count = 0;
  599.                for(a=-1; a<=1; a++){
  600.                    for(b=-1; b<=1; b++){
  601.                          if(the_image[i+a][j+b]==value)
  602.                             count++;
  603.                    }  /*  ends loop over b */
  604.                }  /* ends loop over a */
  605.                if(count > threshold){
  606.                   if(can_dilate(the_image,i,j,value)){
  607.                      out_image[i][j] = value;
  608.                   }  /* ends if can_dilate */
  609.                }  /* ends if count > threshold */
  610.             }  /* ends if the_image == value */
  611.          }  /* ends loop over j */
  612.       }  /* ends loop over i */
  613.  
  614.          /**************************************
  615.          *
  616.          *   Copy the output back to the input.
  617.          *
  618.          **************************************/
  619.  
  620.       for(i=0; i<ROWS; i++)
  621.          for(j=0; j<COLS; j++)
  622.             the_image[i][j] = out_image[i][j];
  623.  
  624.  
  625.          /***************************
  626.          *
  627.          *   Scan top to bottom
  628.          *   Look for value-0 transition
  629.          *
  630.          ****************************/
  631.  
  632.       printf("\n");
  633.       for(j=1; j<COLS-1; j++){
  634.          if( (j%10) == 0) printf("%3d", j);
  635.          for(i=1; i<ROWS-1; i++){
  636.             if(the_image[i-1][j] == value   &&
  637.                the_image[i][j]   == 0){
  638.                count = 0;
  639.                for(a=-1; a<=1; a++){
  640.                    for(b=-1; b<=1; b++){
  641.                          if(the_image[i+a][j+b]==value)
  642.                             count++;
  643.                    }  /*  ends loop over b */
  644.                }  /* ends loop over a */
  645.                if(count > threshold){
  646.                   if(can_dilate(the_image,i,j,value)){
  647.                      out_image[i][j] = value;
  648.                   }  /* ends if can_dilate */
  649.                }  /* ends if count > threshold */
  650.             }  /* ends if the_image == value */
  651.          }  /* ends loop over i */
  652.       }  /* ends loop over j */
  653.  
  654.          /**************************************
  655.          *
  656.          *   Copy the output back to the input.
  657.          *
  658.          **************************************/
  659.  
  660.       for(i=0; i<ROWS; i++)
  661.          for(j=0; j<COLS; j++)
  662.             the_image[i][j] = out_image[i][j];
  663.  
  664.  
  665.  
  666.          /***************************
  667.          *
  668.          *   Scan bottom to top
  669.          *   Do this by scanning top
  670.          *   to bottom and look for
  671.          *   0-value transition.
  672.          *
  673.          ****************************/
  674.  
  675.       printf("\n");
  676.       for(j=1; j<COLS-1; j++){
  677.          if( (j%10) == 0) printf("%3d", j);
  678.          for(i=1; i<ROWS-1; i++){
  679.             if(the_image[i+1][j] == value   &&
  680.                the_image[i][j]   == 0){
  681.                count = 0;
  682.                for(a=-1; a<=1; a++){
  683.                    for(b=-1; b<=1; b++){
  684.                          if(the_image[i+a][j+b]==value)
  685.                             count++;
  686.                    }  /*  ends loop over b */
  687.                }  /* ends loop over a */
  688.                if(count > threshold){
  689.                   if(can_dilate(the_image,i,j,value)){
  690.                      out_image[i][j] = value;
  691.                   }  /* ends if can_dilate */
  692.                }  /* ends if count > threshold */
  693.             }  /* ends if the_image == value */
  694.          }  /* ends loop over i */
  695.       }  /* ends loop over j */
  696.  
  697.          /**************************************
  698.          *
  699.          *   Copy the output back to the input.
  700.          *
  701.          **************************************/
  702.  
  703.       for(i=0; i<ROWS; i++)
  704.          for(j=0; j<COLS; j++)
  705.             the_image[i][j] = out_image[i][j];
  706.  
  707.  
  708.    fix_edges(out_image, 3);
  709.  
  710.    write_array_into_tiff_image(out_name, out_image,
  711.                                il, ie, ll, le);
  712.  
  713. }  /* ends dilate_not_join */
  714.  
  715.  
  716.  
  717.  
  718.  
  719.      /*******************************************
  720.      *
  721.      *   can_dilate(...
  722.      *
  723.      *   This function decides if you can dilate
  724.      *   (set to value) a pixel without joining
  725.      *   two separate objects in a 3x3 area.
  726.      *
  727.      *   First, you grow regions inside the 3x3
  728.      *   area.  Next, check if the center pixel
  729.      *   has neighbors with differing values.
  730.      *   If it does, you cannot dilate it because
  731.      *   that would join two separate objects.
  732.      *
  733.      *******************************************/
  734.  
  735. can_dilate(the_image, i, j, value)
  736.    int   i, j;
  737.    short the_image[ROWS][COLS], value;
  738. {
  739.    int   a, b, c, d, count, found=0,
  740.          no_neighbor,
  741.          stack_pointer=-1,
  742.          stack_empty=1,
  743.          stack[12][2],
  744.          pop_a, pop_b,
  745.          one=1,
  746.          zero=0;
  747.    short first_value, label = 2, temp[3][3];
  748.  
  749.        /**************************************
  750.        *
  751.        *   Copy the center pixel and its
  752.        *   neighbors to the temp array.
  753.        *
  754.        ***************************************/
  755.  
  756.    for(a=-1; a<2; a++)
  757.       for(b=-1; b<2; b++)
  758.          temp[a+1][b+1] = the_image[i+a][b+j];
  759.  
  760.        /**************************************
  761.        *
  762.        *   Grow objects inside the temp array.
  763.        *
  764.        ***************************************/
  765.  
  766.    for(a=0; a<3; a++){
  767.       for(b=0; b<3; b++){
  768.          stack_empty   = 1;
  769.          stack_pointer = -1;
  770.          if(temp[a][b] == value){
  771.             little_label_and_check(temp, stack, label,
  772.                                    &stack_empty,
  773.                                    &stack_pointer,
  774.                                    a, b, value);
  775.             found = 1;
  776.          }  /* ends if temp == value */
  777.  
  778.          while(stack_empty == 0){
  779.             pop_a = stack[stack_pointer][0]; /* POP */
  780.             pop_b = stack[stack_pointer][1]; /* POP */
  781.             --stack_pointer;
  782.             if(stack_pointer <= 0){
  783.                stack_pointer = 0;
  784.                stack_empty   = 1;
  785.             }  /* ends if stack_pointer */
  786.             little_label_and_check(temp, stack, label,
  787.                                    &stack_empty,
  788.                                    &stack_pointer,
  789.                                    pop_a, pop_b, value);
  790.          }  /* ends while stack_empty == 0 */
  791.  
  792.          if(found){
  793.             found = 0;
  794.             label++;
  795.          }  /* ends if object_found */
  796.       }  /* ends loop over b */
  797.    }  /* ends loop over a */
  798.  
  799.        /**************************************
  800.        *
  801.        *   Look at the center pixel.  If it
  802.        *   has two non-zero neigbors whose
  803.        *   pixels are not the same, then
  804.        *   you cannot dilate.
  805.        *
  806.        ***************************************/
  807.  
  808.    first_value = -1;
  809.    for(a=0; a<3; a++){
  810.       for(b=0; b<3; b++){
  811.          if(temp[a][b]  != 0 &&
  812.             first_value == -1){
  813.             first_value = temp[a][b];
  814.          }
  815.          if(temp[a][b]  != 0  &&
  816.             first_value != -1){
  817.             if(temp[a][b] != first_value){
  818.                return(zero);
  819.             }
  820.          }
  821.       }  /* ends loop over b */
  822.    }  /* ends loop over a */
  823.  
  824.    return(one);
  825.  
  826. }  /* ends can_dilate */
  827.  
  828.  
  829.  
  830.  
  831.      /*******************************************
  832.      *
  833.      *   little_label_and_check(...
  834.      *
  835.      *   This function labels the objects in
  836.      *   in a 3x3 area.
  837.      *
  838.      *******************************************/
  839.  
  840. little_label_and_check(temp, stack, label, stack_empty,
  841.                        stack_pointer, a, b, value)
  842.    int   a, b, stack[12][2], 
  843.          *stack_empty, *stack_pointer;
  844.    short temp[3][3], label, value;
  845. {
  846.    int c, d;
  847.  
  848.    temp[a][b] = label;
  849.    for(c=a-1; c<=a+1; c++){
  850.       for(d=b-1; d<=b+1; d++){
  851.          if(c >= 0      &&
  852.             c <= 2      &&
  853.             d >= 0      &&
  854.             d <= 2)
  855.             if(temp[c][d] == value){  /* PUSH */
  856.                *stack_pointer = *stack_pointer + 1;
  857.                stack[*stack_pointer][0] = c;
  858.                stack[*stack_pointer][1] = d;
  859.                *stack_empty = 0;
  860.             }  /* ends if temp == value */
  861.       }  /* ends loop over d */
  862.    }  /* ends loop over c */
  863.  
  864. }  /* ends little_label_and_check */
  865.  
  866.  
  867.